perm filename PUPOP.C[11,HE] blob
sn#688204 filedate 1982-12-06 generic text, type T, neo UTF8
/* LINTLIBRARY */
/*
* pupopen.c
*
* pupopen returns an open Pup Channel between two
* a socket on this host, and a host/net/socket over
* some network. It also decides what sort of
* transport medium to use, and remembers the
* immediate destination address for transmitting packets
* to the remote host (e.g., the address of the first
* gateway.) If the destination is NULL, then it
* is ignored.
*
* pupsetdest changes the destination port for a channel.
* Since this also implies re-routing, the bulk of the
* routing code should go in here; pupopen then just
* calls this routine.
*
* Jeffrey Mogul & Dan Kolkowitz 12-January-1981
* 25-january-1981
* JCM: added routing 21 July 1981
*
*/
#include <puppacket.h>
#include <pupconstants.h>
#include <pupstatus.h>
pupopen(Pchan,srcsock,Dst)
struct PupChan *Pchan; /* channel data structure */
Socket srcsock; /* source socket */
struct Port *Dst; /* destination host/net/socket */
{
int sderr;
Pchan->mystic = PC_MYSTIC; /* mark channel as initialized */
/*
* If the caller has supplied a destination port,
* take care of routing now.
*/
if (Dst != NULL) {
sderr = pupsetdest(Pchan,Dst);
if (sderr != OK) /* probably: NOROUTE */
return(sderr);
}
/*
* Here we would deal with special cases according
* to transport type if there were more than one.
*/
/* FOLLOWING IS UNIX SPECIFIC (ifid and ofid get same fid) !!! */
if ( (Pchan->ifid = enopen()) < 0 )
return(NOCHAN);
else { /* positive fid means it worked */
Pchan->ofid = Pchan->ifid; /* For Unix, file ids are r/w */
Pchan->SrcPort.host = pupgethost(Pchan);
Pchan->SrcPort.net = getnet(Pchan->ifid);
Pchan->SrcPort.socket = srcsock;
Pchan->mode = 0;
#ifdef VAX
Pchan->TimeoutSet = 0; /* remember that no timeout is set */
#endif VAX
return(OK);
}
}
pupsetdest(Pchan, DstPort)
struct PupChan *Pchan; /* channel to set destination on */
struct Port *DstPort; /* new destination */
{
Host via; /* host address for first hop */
/*
* First thing to do is to chose routing.
* If the network specified is zero, then we should NOT
* attempt to determine a route, but should instead
* assume a direct connection to our local net. This
* is necessary because pupopen() is called recursively
* with such an address in the event that a routing table
* does not exist already.
*/
if (DstPort->net) { /* Ok, find a route */
if (puproute(DstPort,&via,NULL) != OK)
return(NOROUTE);
}
else /* use direct routing */
via = DstPort->host;
Pchan->transport = ETHERNET;
Pchan->ImmNet = 0; /* this should be better! */
Pchan->ImmHost = via;
Pchan->DstPort.host = DstPort->host;
Pchan->DstPort.net = DstPort->net;
Pchan->DstPort.socket = DstPort->socket;
Pchan->SrcPort.net = getnet(Pchan->ifid);
/* this may not have been right before */
return(OK);
}